/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package structures.grammar;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import structures.table.symboltable.ItemInfo;
import structures.table.symboltable.NonTerminalInfo;

/**
 *
 * @author Slayer
 */
public class Grammar {

    private HashMap<String, List<Rule>> grammar;
    private Rule firstRule;
    private ItemList uniqueItems;

    public Grammar() {
        grammar = new HashMap<String, List<Rule>>();
        uniqueItems = new ItemList();
    }

    public List<Rule> get(String ruleName) {
        return grammar.get(ruleName);
    }

    public Rule getFirstRule() {
        return firstRule;
    }

    public ItemInfo getFirstSymbol() {
        return firstRule.getFrom();
    }

    public void setFirstRule(Rule newFirstRule) {
        firstRule = newFirstRule;
    }

    public ItemList getUniqueItems() {
        return uniqueItems;
    }

    public void extend() {
        Rule newRule;
        ItemInfo from = getFirstRule().getFrom();
        ItemInfo setName = new NonTerminalInfo("'" + from.getName());
        ItemList to = new ItemList();

        to.add(getFirstRule().getFrom());
        newRule = new Rule(setName, to);
        put(newRule);
        setFirstRule(newRule);
    }

    public void put(Rule rule) {
        String ruleName = rule.getFrom().getName();

        if (firstRule == null) {
            firstRule = rule;
        }

        if (grammar.containsKey(ruleName)) {
            grammar.get(ruleName).add(rule);
        } else {
            List<Rule> list = new LinkedList<Rule>();

            grammar.put(ruleName, list);
            list.add(rule);
        }

        //add new unique items
        if (!uniqueItems.contains(rule.getFrom())) {
            uniqueItems.add(rule.getFrom());
        }

        for (ItemInfo item : rule.getTo()) {
            if (!uniqueItems.contains(item)) {
                uniqueItems.add(item);
            }
        }
    }
}
